package cn.liberals.pet.service.impl;

import cn.liberals.basic.exception.BusinessException;
import cn.liberals.basic.utils.*;
import cn.liberals.order.domain.OrderPetAcquisition;
import cn.liberals.order.mapper.OrderPetAcquisitionMapper;
import cn.liberals.org.domain.Shop;
import cn.liberals.org.mapper.ShopMapper;
import cn.liberals.pet.domain.Pet;
import cn.liberals.pet.domain.SearchMasterMsg;
import cn.liberals.pet.domain.SearchMasterMsgAuditLog;
import cn.liberals.pet.dto.HandlerMsgDto;
import cn.liberals.pet.mapper.PetMapper;
import cn.liberals.pet.mapper.SearchMasterMsgAuditLogMapper;
import cn.liberals.pet.mapper.SearchMasterMsgMapper;
import cn.liberals.pet.service.ISearchMasterMsgService;
import cn.liberals.basic.service.impl.BaseServiceImpl;
import cn.liberals.user.domain.User;
import com.alibaba.fastjson.JSONObject;
import jdk.management.resource.internal.inst.InitInstrumentation;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.xmlbeans.impl.xb.ltgfmt.Code;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author liberals
 * @since 2022-07-19
 */
@Service
public class SearchMasterMsgServiceImpl extends BaseServiceImpl<SearchMasterMsg> implements ISearchMasterMsgService {
    @Autowired
    private SearchMasterMsgMapper searchMasterMsgMapper;

    @Autowired
    private SearchMasterMsgAuditLogMapper searchMasterMsgAuditLogMapper;

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private PetMapper petMapper;

    @Autowired
    OrderPetAcquisitionMapper orderPetAcquisitionMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    /*
    * @Title: publish
    * @Description: 发布寻主消息
    * @Author: liberals
    * @Version: 1.0
    * @Date:  2022/7/19 19:21
    * @Parameters:
    * @Return
    */
    public void publish(SearchMasterMsg searchMasterMsg, User user) {
        // 1.保存寻主消息
        searchMasterMsgMapper.save(searchMasterMsg);
        // 2.审核寻主消息，如果公司有定制的自动审核还需要开启定制自动审核
        StringBuffer sbr = new StringBuffer()
                .append(searchMasterMsg.getName())
                .append(searchMasterMsg.getAddress())
                .append(searchMasterMsg.getNote())
                .append(searchMasterMsg.getCoatColor());
        // 3.判断审核是否通过
        if (!BaiduAuditUtils.TextCensor(sbr.toString())){ // 3.1.审核不通过，保存审核失败日志，并发送短信通知用户修改
            // 保存审核日志
            searchMasterMsg.setState(-1);
            SearchMasterMsgAuditLog searchMasterMsgAuditLog = new SearchMasterMsgAuditLog();
            searchMasterMsgAuditLog.setMsgId(searchMasterMsg.getId());
            searchMasterMsgAuditLog.setAuditTime(new Date());
            searchMasterMsgAuditLog.setState(0);
            searchMasterMsgAuditLog.setNote("填入的信息不合法，可能是：名称、地址、描述、毛色等");
            searchMasterMsgAuditLogMapper.save(searchMasterMsgAuditLog);
            // 发送短信通知用户
            SmsUtils.sendMsg(user.getPhone(), "亲，您的寻主消息审核未通过，请修改敏感信息后重新发起审核！");
        }else{// 3.2.审核通过，使用百度地图计算距离的工具算出否有小于50公里的店铺
            searchMasterMsg.setState(1);
            // 1.调用工具类方法算出寻主地址的经度纬度
            Point point = DistanceUtil.getPoint(searchMasterMsg.getAddress());
            // 2.找到小于50公里的店铺
            List<Shop> shops = shopMapper.loadAll();
            Shop shop = DistanceUtil.getNearestShop(point, shops);
            // 3.判断是否找到
            if (shop != null){ // 1.找到那么将此寻主消息绑定店铺
                searchMasterMsg.setShopId(shop.getId());
                // 发送短信通知商家，此处真实开发中会推送消息到店铺消息中心
                SmsUtils.sendMsg(shop.getTel(), "亲，您有新的寻主订单，请尽快处理！");
            }
        }
        // 4.没有找到那么此寻主消息没有绑定店铺，就在寻主池中，修改寻主消息
        searchMasterMsgMapper.update(searchMasterMsg);
    }

    /*
    * @Title: accept
    * @Description: 店铺员工接单
    * @Author: liberals
    * @Version: 1.0
    * @Date:  2022/7/26 17:28
    * @Parameters:
    * @Return
    */
    @Override
    public void accept(HandlerMsgDto handlerMsgDto) {
        // 校验参数是否为空
        Long handler = handlerMsgDto.getHandler();
        Long msgId = handlerMsgDto.getMsgId();
        String note = handlerMsgDto.getNote();
        if (StringUtils.isEmpty(note) || handler != null || msgId != null){
            throw new BusinessException("参数不能为空！");
        }
        // 1.确定是否已经被接单，万一有两个人同时点击接单，怎么办？以后我们用加锁处理，现在我们先查询一下
        /*
            情况分析：state != -1 searcherMasterMsgId = handlerMsgDto.msgId
                1.当前寻主消息是第一次被接单，那么没有在收购订单中应该查询不到
                2.当前寻主消息不是第一次被接单了，那么说明之前生成过
                3.如何判定是否可以接单：
                    1.如果查询不到收购单那么就可以接单
                    2.即便查询的到收购单，但是收购单的消息需要为-1，只要不是-1，并且查询到了，都不能接单
        */
        OrderPetAcquisition orderPetAcquisition = orderPetAcquisitionMapper.loadByOrderReceived(handlerMsgDto.getMsgId());
        if(orderPetAcquisition != null){
            throw new BusinessException("订单被抢了");
        }
        // 1.查询寻主消息
        SearchMasterMsg searchMasterMsg = searchMasterMsgMapper.loadById(handlerMsgDto.getMsgId());
        // 2.生成宠物信息，并保存
        Pet pet = msgPet(searchMasterMsg);
        // 需要返回主键
        petMapper.save(pet);
        // 3.初始化订单对象并保存
        orderPetAcquisition = initOrderPetAcquisition(handlerMsgDto,searchMasterMsg,pet);
        orderPetAcquisitionMapper.save(orderPetAcquisition);

        Map<String,Object> orderMap = new HashMap<>();
        orderMap.put("orderPetAcquisition","1357890");
        orderMap.put("createTime", LocalDateTime.now());

        //参数一：topic   如果想添加tag,可以使用"topic:tag"的写法
        //参数二：Message<?>
        //参数三：消息发送超时时间
        //参数四：delayLevel 延时level  messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
        rocketMQTemplate.syncSend("订单延迟时间", MessageBuilder.withPayload(JSONObject.toJSONString(orderMap)).build(),3000,3);


    }

    /*
     * @Title: accept
     * @Description: 店铺员工拒单
     * @Author: liberals
     * @Version: 1.0
     * @Date:  2022/7/26 17:28
     * @Parameters:
     * @Return
     */
    @Override
    public void reject(Long msgId) {
        // 1.参数校验
//        if (msgId == null){
//            throw new BusinessException("参数不能为空");
//        }
        // 2.根据消息Id查询寻主消息，将shopId置空，并修改
        SearchMasterMsg searchMasterMsg = searchMasterMsgMapper.loadById(msgId);
        if (searchMasterMsg == null){
            throw new BusinessException("此订单不存在！");
        }
        searchMasterMsg.setShopId(null);
        searchMasterMsgMapper.update(searchMasterMsg);
        // 3.记录日志
    }

    private OrderPetAcquisition initOrderPetAcquisition(HandlerMsgDto handlerMsgDto, SearchMasterMsg searchMasterMsg, Pet pet){
        // 3.生成收购单
        OrderPetAcquisition orderPetAcquisition = new OrderPetAcquisition();
        // 使用工具类生成订单编号
        String orderSn = CodeGenerateUtils.generateOrderSn(searchMasterMsg.getUserId());
        orderPetAcquisition.setOrderSn(orderSn);
        orderPetAcquisition.setOrderSn(handlerMsgDto.getNote());
        // 最迟的处理订单的时间
        orderPetAcquisition.setLastcomfirmtime(new Date(System.currentTimeMillis() + 2*24*60*60*1000));
        // 这时候还不是最终价格，因为我们销售人员可以去讲价，加价之后的才是最终价格
        orderPetAcquisition.setPetId(pet.getId());
        orderPetAcquisition.setPrice(searchMasterMsg.getPrice());
        orderPetAcquisition.setUserId(searchMasterMsg.getUserId());
        orderPetAcquisition.setAddress(searchMasterMsg.getAddress());
        orderPetAcquisition.setShopId(searchMasterMsg.getShopId());
        orderPetAcquisition.setEmpId(handlerMsgDto.getHandler());
        orderPetAcquisition.setSearchMasterMsgId(searchMasterMsg.getId());
        return orderPetAcquisition;
    }

    private Pet msgPet(SearchMasterMsg searchMasterMsg) {
        // 2.根据寻主消息初始化宠物信息
        Pet pet = new Pet();
        pet.setName(searchMasterMsg.getName());
        pet.setCostprice(searchMasterMsg.getPrice());
        pet.setTypeId(searchMasterMsg.getPetType());
        pet.setShopId(searchMasterMsg.getShopId());
        pet.setSearchMasterMsgId(searchMasterMsg.getId());
        return pet;
    }
}
